package room

import (
	"errors"
	"server/common"

	"github.com/mitchellh/mapstructure"
	"github.com/sirupsen/logrus"
)

// -------------------------------------------------------------------------------------------------
//
// -------------------------------------------------------------------------------------------------
func (s *RoomService) checkCreateTransportReqData(data common.SFUCreateTransportReqData) error {
	// Check if room ID provided
	if data.RoomId == "" {
		return errors.New("room ID is required in create transport request")
	}
	// Check sctp capabilities
	if data.SctpCaps == nil {
		return errors.New("sctp capabilities are required in create transport request")
	}
	// Check if room exists
	if !s.roomMgr.RoomExists(data.RoomId) {
		return errors.New("room does not exist")
	}

	if !data.Producing && !data.Consuming {
		return errors.New("either producing or consuming must be enabled in create transport request")
	}

	if data.Producing && data.Consuming {
		return errors.New("cannot create transport with both producing and consuming enabled")
	}

	if data.Producing && s.roomMgr.SendTransportExists(data.RoomId, data.UserId) {
		return errors.New("user already has a send transport in the room")
	}

	if data.Consuming && s.roomMgr.RecvTransportExists(data.RoomId, data.UserId) {
		return errors.New("user already has a receive transport in the room")
	}

	return nil
}

// -------------------------------------------------------------------------------------------------
//
// -------------------------------------------------------------------------------------------------
func (s *RoomService) handleCreateTransportReq(msg common.Message, from common.ServiceInfo,
	connId string) error {
	LOG().WithFields(logrus.Fields{
		"msg":    common.ToJson(msg),
		"from":   from,
		"connId": connId,
	}).Info("Handling SFU Create Transport Request")

	var reqData common.SFUCreateTransportReqData
	if err := mapstructure.Decode(msg.Data, &reqData); err != nil {
		return errors.New("failed to decode create transport request data: " + err.Error())
	}

	if err := s.checkCreateTransportReqData(reqData); err != nil {
		return err
	}

	var sfuResData common.ResMsgData

	transport, err := s.roomMgr.CreateTransport(msg.Rid, reqData)
	if err != nil {
		sfuResData = common.ResMsgData{
			Code: 1,
			Msg:  "failed to create transport: " + err.Error(),
		}
	} else {
		sfuResData = common.ResMsgData{
			Code: 0,
			Msg:  "success",
			Data: common.SFUCreateTransportResData{
				RoomId:         reqData.RoomId,
				UserId:         reqData.UserId,
				TransportType:  reqData.TransportType,
				TransportId:    transport.TransportId,
				IceParameters:  transport.IceParameters,
				IceCandidates:  transport.IceCandidates,
				DtlsParameters: transport.DtlsParameters,
				SctpParameters: transport.SctpParameters,
			},
		}
	}

	resMsg := common.Message{
		Cmd:  common.SFU_CREATE_TRANSPORT_RES,
		Rid:  msg.Rid,
		Data: sfuResData,
	}

	s.dispatcher.Dispatch(resMsg, s.serviceInfo, from, connId)

	return nil
}
